package com.ly.friend.service.exam.Impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ly.common.core.constants.Constants;
import com.ly.common.core.domain.R;
import com.ly.common.core.domain.TableDataInfo;
import com.ly.common.core.utils.ThreadLocalUtil;
import com.ly.common.redis.service.RedisService;
import com.ly.friend.domain.exam.dto.ExamQueryDTO;
import com.ly.friend.domain.exam.vo.ExamVO;
import com.ly.friend.manager.exam.ExamCacheManager;
import com.ly.friend.mapper.exam.ExamMapper;
import com.ly.friend.service.exam.IExamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class ExamService implements IExamService {

    @Autowired
    private ExamMapper examMapper;

    @Autowired
    private ExamCacheManager examCacheManager;

    @Autowired
    private RedisService redisService;

    public List<ExamVO> list(ExamQueryDTO examDTO) {
        PageHelper.startPage(examDTO.getPageNum(), examDTO.getPageSize());
        return examMapper.selectExamList(examDTO);
    }

    @Override
    public TableDataInfo redisList(ExamQueryDTO examQueryDTO) {
//        Long userId= ThreadLocalUtil.get(Constants.USER_ID,Long.class);
        //从redis中获取 竞赛列表的数据
        //新的竞赛在经过修改之后直接存储到缓存(redis中),在此之前添加的竞赛,经过列表查询
        //如果redis中没有数据,添加到redis中(注意:如果redis中原本存在数据,这种方式则失效)
        Long total = examCacheManager.getListSize(examQueryDTO.getType(),null);
        List<ExamVO> examVOList;
        if(total == null || total <= 0){//缓存不存在时的处理：
            examVOList = list(examQueryDTO);
            //将数据库中的数据同步给缓存
            examCacheManager.refreshCache(examQueryDTO.getType(),null);
            //从数据库中查询
            total=new PageInfo<>(examVOList).getTotal();
        }else{//缓存存在时的处理：
            examVOList = examCacheManager.getExamVOList(examQueryDTO,null);
            //从redis中查询,在查询时,出现异常情况,可能会重新刷新数据,这次查询用户数据的更新
//            0:代表未完赛 1:表示开始竞赛
            total = examCacheManager.getListSize(examQueryDTO.getType(),null);
        }
//        空结果处理：
        if  (CollectionUtil.isEmpty(examVOList)){
            return TableDataInfo.empty();
         }
        assembleExamVOList(examVOList);
        //获取符合查询条件的数据总数
        //从数据库中查询数据,不是从redis中查询数据
        return TableDataInfo.success(examVOList,total);
    }

    @Override
    public String getFirstQuestion(Long examId) {
        checkAndRefresh(examId);

        return examCacheManager.getFirstQuestion(examId).toString();
    }

    @Override
    public String preQuestion(Long examId, Long questionId) {
        checkAndRefresh(examId);
        return examCacheManager.preQuestion(examId, questionId).toString();

    }

    @Override
    public String nextQuestion(Long examId, Long questionId) {
        checkAndRefresh(examId);
        return examCacheManager.nextQuestion(examId, questionId).toString();
    }

    private void assembleExamVOList(List<ExamVO> examVOList){
        Long userId = ThreadLocalUtil.get(Constants.USER_ID, Long.class);
        //把用户报名参加的竞赛拿出来
        List<Long> userExamIdList=examCacheManager.getAllUserExamList(userId);
        if (CollectionUtil.isEmpty(userExamIdList)) {
            return;
        }
        for(ExamVO examVO :examVOList){
            if(userExamIdList.contains(examVO.getExamId())){
                examVO.setEnter(true);
            }
        }
    }

    private void checkAndRefresh(Long examId) {
        Long listSize = examCacheManager.getExamQuestionListSize(examId);
        if (listSize == null || listSize <= 0) {
            examCacheManager.refreshExamQuestionCache(examId);
        }
    }
}
